0001
0009 import Foundation
0010
0011 let primes| BigUInt Prime Test.swift:86 | for i in 1 ..< primes.count { |
| BigUInt Prime Test.swift:87 | let p = primes[i] |
| BigUInt Prime Test.swift:99 | guard isStrongProbablePrime(BigUInt(primes[i])) else { |
: [BigUInt.Digit] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41]
0015
0016 let pseudoPrimes| BigUInt Prime Test.swift:97 | if self < pseudoPrimes.last! { |
| BigUInt Prime Test.swift:98 | for i in 0 ..< pseudoPrimes.count { |
| BigUInt Prime Test.swift:102 | if self < pseudoPrimes[i] { |
: [BigUInt] = [
0021 2_047,
0022 1_373_653,
0023 25_326_001,
0024 3_215_031_751,
0025 2_152_302_898_747,
0026 3_474_749_660_383,
0027 341_550_071_728_321,
0028 341_550_071_728_321,
0029 3_825_123_056_546_413_051,
0030 3_825_123_056_546_413_051,
0031 3_825_123_056_546_413_051,
0032 "318665857834031151167461",
0033 "3317044064679887385961981",
0034 ]
0035
0036 extension BigUInt {
0037
0039 @warn_unused_result
0043 public func isStrongProbablePrime| BigUInt Prime Test.swift:99 | guard isStrongProbablePrime(BigUInt(primes[i])) else { |
| BigUInt Prime Test.swift:113 | guard isStrongProbablePrime(random) else { |
(base: BigUInt) -> Bool {
0044 let dec = self - 1
0045
0046 let r = dec.trailingZeroes
0047 let d = dec >> r
0048
0049 var test = base.power(d, modulus: self)
0050 if test == 1 || test == dec { return true }
0051
0052 if r > 0 {
0053 for _ in 1 ..< r {
0054 test = (test * test) % self
0055 if test == 1 {
0056 return false
0057 }
0058 if test == dec { return true }
0059 }
0060 }
0061 return false
0062 }
0063
0064 @warn_unused_result
0078 public func isPrime(rounds rounds: Int = 10) -> Bool {
0079 if count <= 1 && self[0] < 2 { return false }
0080 if count == 1 && self[0] < 4 { return true }
0081
0082 if self[0] & 1 == 0 { return false }
0084
0085 for i in 1 ..< primes.count {
0087 let p = primes[i]
0088 if self.count == 1 && self[0] == p {
0089 return true
0090 }
0091 if self.divideByDigit(p).mod == 0 {
0092 return false
0093 }
0094 }
0095
0096 if self < pseudoPrimes.last! {
0098 for i in 0 ..< pseudoPrimes.count {
0099 guard isStrongProbablePrime(BigUInt(primes[i])) else {
0100 break
0101 }
0102 if self < pseudoPrimes[i] {
0103 return true
0105 }
0106 }
0107 return false
0108 }
0109
0110 for _ in 0 ..< rounds {
0112 let random = BigUInt.randomIntegerLessThan(self)
0113 guard isStrongProbablePrime(random) else {
0114 return false
0115 }
0116 }
0117
0118 return true
0120 }
0121 }